package com.teamwork.module03.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.teamwork.common.entity.module03.Article;
import com.teamwork.common.entity.module03.ArticleCares;
import com.teamwork.common.entity.module03.ArticleLikes;
import com.teamwork.common.entity.module03.Author;
import com.teamwork.common.entity.module03.dto.ArticleDto;
import com.teamwork.common.entity.module03.requestentity.ReqArticleBody;
import com.teamwork.common.result.Result;
import com.teamwork.module03.mapper.ArticleCaresMapper;
import com.teamwork.module03.mapper.ArticleMapper;
import com.teamwork.module03.service.*;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collector;
import java.util.stream.Collectors;

@Service
@Slf4j
public class ArticleServiceImpl extends ServiceImpl<ArticleMapper, Article> implements ArticleService {

//    @Resource
//    private UserServiceImpl userServiceImplr;
        @Resource
        private AuthorService authorService;
        @Resource
        @Lazy //懒加载 ，防止互相依赖错误
        private CommentService commentService;
        @Resource
        private ReplyService replyService;
        @Resource
        private ArticleCaresService articleCaresService;
        @Resource
        private ArticleLikeService articleLikeService;
        @Resource
        private MessageService messageService;
    @Value("${txt.path}")
    private String txtpath;
    /**
     * 分页查询文章列表
     * @param page
     * @param size
     * @return
     */
    @Override
    public Result getArticles(Integer page, Integer size,String searchname) {
        Page<Article> pageinfo  = new Page<>(page,size);

        //关键字查询
        LambdaQueryWrapper<Article> wrapper =new LambdaQueryWrapper<>();
        //只能查询审核通过的文章
        wrapper.eq(Article::getStatus,1);

        if(!searchname.equals("")){



            LambdaQueryWrapper<Author> authorWrapper = new LambdaQueryWrapper<>();
            authorWrapper.like(Author::getNickname,searchname);
            List<Author> list = authorService.list(authorWrapper);


            if(list.size()!=0){

                List<Long> authorids   =  list.stream().map(Author::getId).collect(Collectors.toList());

           //转换为String类型的集合
                //再转换为String类型的数组
                String[] arr = authorids.stream(). map(Object::toString).toArray(String[]::new);

                //in 查询
                wrapper.like(Article::getTitle,searchname).or().in(Article::getAuthorId,arr);

                this.page(pageinfo,wrapper);

            }else {
                //该关键字不是作者，只查询文章标题
                wrapper.like(Article::getTitle,searchname);
                this.page(pageinfo, wrapper);
            }
        }else {
            //正常查询
             this.page(pageinfo,wrapper);
        }
        
        
       // Page<Article> pageinfo  = new Page<>(page,size);

        /**
         * 共有的部分，都要设置nickname
         */

        List<Article> records = pageinfo.getRecords();

        List<ArticleDto> articleDtoList = new ArrayList<>();

        for (Article article : records) {
            //查询文章的作者昵称
            Long authorId = article.getAuthorId();
            String nickname = authorService.getNickNameById(authorId);
            ArticleDto articleDto = new ArticleDto(article, "", nickname);
            articleDtoList.add(articleDto);
        }

        Page<ArticleDto> respage = new Page<>();
        //设置记录
        respage.setRecords(articleDtoList);
        //赋值属性
        BeanUtils.copyProperties(pageinfo,respage,"records");

        return Result.success(respage);
    }

    /**
     * 根据id查询文章
     * @param id
     * @return
     */
    @Override
    public Result getArticleById(Integer id) {
        Article artcile = this.getById(id);

        return Result.success(artcile);

    }

    @Override
    public Result getTxt(String name, HttpServletResponse response) throws FileNotFoundException {
        System.out.println(txtpath+name);
        try{
            response.setHeader("Content-type", "text/html;charset=UTF-8");
            InputStream reader = new FileInputStream(txtpath+name);
            ServletOutputStream writer = response.getOutputStream();
            byte[] buff =new byte[1024];
            while ((reader.read(buff,0,buff.length))!=-1){
                writer.write(buff);
                writer.flush();
            }

            reader.close();
            writer.close();
            return Result.success();
        }catch (FileNotFoundException e){
            return Result.failure("文件找不到！");
        } catch (IOException e) {
            throw new RuntimeException(e);
        }




    }

    /**@
     * 管理端的分页查询
     * @param reqBody 请求参数实体
     *               （page:页数，size：尺寸，status：状态,liketitle:标题模糊查询
     * @return Result
     */
    @Override
    public Result getArticlesInManger(ReqArticleBody reqBody) {

        Integer status = reqBody.getStatus();
        String likeTitle = reqBody.getLiketitle();

        Page<Article> articlePage = new Page<>(reqBody.getPage(),reqBody.getSize());
        LambdaQueryWrapper<Article> wrapper = new LambdaQueryWrapper<>();

        if(likeTitle==null&&status!=3){
           //如果转态不是一般且没有查询字段，则根据转态查询
            wrapper.eq(Article::getStatus,status).orderByDesc(Article::getCreatetime);
            this.page(articlePage,wrapper);
        } else if (likeTitle!=null&&status!=3) {
            //字段不为空且转态不是一般转态，按照两者并且
            wrapper.eq(Article::getStatus,status).like(Article::getTitle,likeTitle).
                    orderByDesc(Article::getCreatetime);
            this.page(articlePage,wrapper);
        } else if(likeTitle!=null && status==3) {
             wrapper.like(Article::getTitle,likeTitle).orderByDesc(Article::getCreatetime);
             this.page(articlePage,wrapper);
        }else if(likeTitle==null && status==3){
            //状态为一般状态，且没有查询字段 就正常查询
            this.page(articlePage);
        }


        List<Article> articles = articlePage.getRecords();

        List<ArticleDto> articleDtoList = new ArrayList<>();

        for (Article article : articles) {
            Long authorId = article.getAuthorId();
            String username = authorService.getUserNameById(authorId);
            String nickname = authorService.getNickNameById(authorId);

            ArticleDto articleDto = new ArticleDto(article,username,nickname);
            articleDtoList.add(articleDto);
        }

        Page<ArticleDto> articleDtoPage = new Page<>();
        articleDtoPage.setRecords(articleDtoList);
        articleDtoPage.setCurrent(articlePage.getCurrent());
        articleDtoPage.setTotal(articlePage.getTotal());
        articleDtoPage.setSize(articlePage.getSize());


        return Result.success(articleDtoPage);
    }

    /**
     * 根据id审核文章
     * @param id 文章id
     * @param status 文章状态
     * @return
     */
    @Override
    public Result checkArticle(Integer id,Integer status) {

        Article article = this.getById(id);
        article.setStatus(status);
        boolean b = this.updateById(article);
        if(b){
            String txt;
            if(status==1) txt = "已审核"; else txt = "未通过";
            log.info("文章id为:"+id+"状态修改成功...结果是:{}",txt);
            //先把userid查出来

            Long userId = authorService.getById( this.getById(id).getAuthorId()).getUserId();


            //给message中保存一条消息，告诉用户审核结果
            messageService.addCheckResult(status,userId,article.getTitle());

            return  Result.success("状态修改成功!");
        }else{
            log.error("文章id为:"+id+"的状态修改失败!");
            return Result.failure("状态修改失败！");
        }

    }

    /**
     * 删除单个文章
     * @param id
     * @return
     */
    @Override
    public Result deleteOne(Integer id) {

        boolean b = this.removeById(id);
        if(b){
            log.info("删除了一条文章记录：id:{}",id);
            return Result.success();
        }else {
            log.error("删除文章失败：id:{}",id);
            return Result.failure("删除失败!");
        }
    }

    /**
     * 批量删除文章
     * @param ids 文章id
     * @return Result
     */
    @Override
    public Result deleteBuch(List<Integer> ids) {

        boolean b = this.removeBatchByIds(ids);
        if(b){
            log.info("批量删除文章:尺寸:{},ids:{}",ids.size(),ids);
            return Result.success("删除成功");
        }else {
            log.error("批量删除文章失败!!!:尺寸:{},ids:{}",ids.size(),ids);
            return Result.failure("删除失败!");
        }

    }

    /**
     * 根据作者id删除文章
     * @param authorid 作者id
     * @return 是否删除
     */
    @Override
    public boolean deleteByAuId(Integer authorid) {
        LambdaQueryWrapper<Article> wrapper=new LambdaQueryWrapper<>();
        wrapper.eq(Article::getAuthorId,authorid);
        List<Article> articles = this.list(wrapper);
        if(articles.size()==0){
            return true;
        }
        for (Article article : articles) {
            Long articleId = article.getId();
            //把文章的评论和所有的回复都删除了
           commentService.deleteByArticleId(articleId);
           //删除该文章所有的回复
           replyService.deleteByArticeId(articleId);
        }
         //最后把该文章删除了
        boolean b = this.remove(wrapper);
        if(b){
            log.info("根据作者id: {} 删除该作者所有文章记录",authorid);
        }//else  log.error("根据作者id: {} 删除该作者所有文章记录出错",authorid);
        return b;
    }

    /**
     * 根据作者id查询文章
     * @param authorid
     * @return
     */
    @Override
    public Result getArticlesByAuthorId(Long authorid) {
        LambdaQueryWrapper<Article> wrapper=new LambdaQueryWrapper<>();
        wrapper.eq(Article::getAuthorId,authorid);
        List<Article> list = this.list(wrapper);
        if(list==null){
            return Result.success("该作者没有文章");
        }
        return Result.success(list);
    }

    /**
     * 返回具体的文章集合
     * @param authorid
     * @return
     */
    @Override
    public List<Article> getArtListByAuId(Integer authorid) {
        LambdaQueryWrapper<Article> wrapper=new LambdaQueryWrapper<>();
        wrapper.eq(Article::getAuthorId,authorid);
        return this.list(wrapper);
    }

    /**
     * 根据文章id吧评论数加一
     * @param aid
     */
    @Override
    public void addCommentCount(int aid) {
        Article art = this.getById(aid);
        art.setComments(art.getComments()+1);
        this.updateById(art);
    }

    /**
     * 根据用户id收藏文章
     * @param userid 用户id
     * @param artid  文章id
     * @return Result
     */
    @Override
    public Result tocareArticle(Integer userid, Integer artid) {
        boolean b = articleCaresService.InsertOneByUserId(userid, artid);
        if(b){
            Article article = this.getById(artid);
            return Result.success("收藏成功");
        }
        return Result.failure("收藏失败！后台出错");
    }

    /**
     * 根据用户id和文章id查查文章的收藏状态
     * @param userid 用户id
     * @param artid 文章id
     * @return result
     */
    @Override
    public Result getArticleCareStatus(Integer userid, Integer artid) {
        ArticleCares one = articleCaresService.getByUidAndAid(userid, artid);
        if(one!=null) return Result.success("文章已被该用户id:"+userid+"收藏");
        return Result.failure("该文章没有被该用户id:"+userid+"收藏");
    }

    /**
     * 取消收藏文章
     * @param userid 用户id
     * @param artid 文章id
     * @return
     */
    @Override
    public Result delcareArticle(Integer userid, Integer artid) {
        boolean b = articleCaresService.deleteOneByUidAndAid(userid, artid);
        if(b){
            log.info("用户id:{}取消收藏文章id:{}",userid,artid);
            return Result.success("已经取消收藏文章id:"+artid);
        }
         log.error("用户id:{}取消收藏文章id:{}失败!!!",userid,artid);
        return Result.failure("取消收藏失败，后台错误！！！");
    }

    /**
     * 根据用户id和文章id点赞文章
     * @param userid 用户id
     * @param artid 文章id
     * @return result
     */
    @Override
    public Result tolikeArticle(Integer userid, Integer artid) {
        boolean b = articleLikeService.InsertOneByUidAndAid(userid, artid);
        if(b){
            //将文章的点赞数加一
            Article art = this.getById(artid);
            art.setLikes(art.getLikes()+1);
            this.updateById(art);

            log.info("用户id:{} 点赞了文章id:{}",userid,artid);
            return Result.success("点赞文章id:"+artid+"成功");
        }else {
            log.error("用户id:{} 点赞了文章id:{}出错！！！",userid,artid);
            return Result.failure("点赞文章id:"+artid+"失败，后台错误！");
        }
    }

    /**
     * 根据用户id，文章id 取消点赞
     * @param userid 用户id
     * @param artid 文章id
     * @return result
     */
    @Override
    public Result delLikeArticle(Integer userid, Integer artid) {

        boolean b = articleLikeService.deleteByUidAndAid(userid, artid);
        if(b){
            //文章点赞数减一
            Article art = this.getById(artid);
            art.setLikes(art.getLikes()-1);
            this.updateById(art);

            log.info("用户id:{} 取消点赞文章id:{}",userid,artid);
            return Result.success("取消点赞文章id:"+artid+"成功！");
        }else {
            log.error("用户id:{} 取消点赞文章id:{}失败!!!",userid,artid);
            return Result.failure("取消点赞文章id:"+artid+"失败！");
        }
    }

    /**
     * 根据用户id 文章id查询点赞状态
     * @param userid 用户id
     * @param artid 文章id
     * @return result
     */
    @Override
    public Result getLikeArtStatus(Integer userid, Integer artid) {

        ArticleLikes like = articleLikeService.getByUseridAndArtid(userid, artid);
        if(like!=null){
            //点赞过
            return Result.failure("该用户已经已经点赞过文章id:"+artid);
        }
        return Result.success("该用户没有点赞过该文章id:"+artid);
    }

    /**
     * 获取用户已经发布的文章集合
     * @param userid 用户id
     */
    @Override
    public List<Article> getArtArdyPubByUId(Integer userid) {
        Long id = authorService.getByUserId(userid).getId();
        LambdaQueryWrapper<Article> wrapper=new LambdaQueryWrapper<>();
        wrapper.eq(Article::getStatus,1).eq(Article::getAuthorId,id);

      return   this.list(wrapper);

    }

    /**
     * 获取我发布的文章
     * @param userid 用户id
     * @return
     */
    @Override
    public Result getMyArticles(Integer userid) {

        Author author = authorService.getByUserId(userid);
        if(author==null){
            return Result.failure("没有该作者");
        }

        Long authorId = author.getId();

        String nickname = author.getNickname();

         LambdaQueryWrapper<Article> wrapper=new LambdaQueryWrapper<>();
         wrapper.eq(Article::getAuthorId,authorId).orderByDesc(Article::getCreatetime);

        List<Article> articles = this.list(wrapper);

       List<ArticleDto> articleDtoList =new ArrayList<>();

       articles.forEach(it->{
           ArticleDto articleDto=new ArticleDto(it,"",nickname);
           articleDtoList.add(articleDto);
       });

        return Result.success(articleDtoList);
    }

    /**
     * 获取我收藏的文章
     * @param userid 用户id
     * @return
     */
    @Override
    public Result getMyStars(Integer userid) {

        List<Integer> artids = articleCaresService.getMyCaresArtIds(userid);

        LambdaQueryWrapper<Article> wrapper=new LambdaQueryWrapper<>();
        wrapper.in(Article::getId,artids).orderByDesc(Article::getCreatetime);

        List<Article> articles = this.list(wrapper);

        List<ArticleDto> articleDtoList =new ArrayList<>();

        articles.forEach(it->{
            String nickname = authorService.getNickNameById(it.getAuthorId());
            ArticleDto articleDto=new ArticleDto(it,"",nickname);
            articleDtoList.add(articleDto);
        });

        return Result.success(articleDtoList);


    }

}
